from pyalgotrade.barfeed.csvfeed import GenericBarFeed
from pyalgotrade.bar import Frequency

from pyalgotrade.technical import ma
from pyalgotrade.technical import cross

from pyalgotrade import strategy
from pyalgotrade.stratanalyzer import returns
from pyalgotrade.stratanalyzer import sharpe
from pyalgotrade.stratanalyzer import drawdown
from pyalgotrade.stratanalyzer import trades
from pyalgotrade import plotter

import matplotlib as mpl
mpl.style.use('classic')

class SMACrossOver(strategy.BacktestingStrategy):
    def __init__(self, feed, instrument, smaPeriod):
        super(SMACrossOver, self).__init__(feed)
        self._instrument = instrument
        self._position = None
        # We'll use adjusted close values instead of regular close values.
        self.setUseAdjustedValues(True)
        self._prices = feed[instrument].getPriceDataSeries()
        self._sma = ma.SMA(self._prices, smaPeriod)

    def getSMA(self):
        return self._sma

    def onEnterCanceled(self, position):
        self._position = None

    def onExitOk(self, position):
        self._position = None

    def onExitCanceled(self, position):
        # If the exit was canceled, re-submit it.
        self._position.exitMarket()

    def onBars(self, bars):
        # If a position was not opened, check if we should enter a long position.
        if self._position is None:
            if cross.cross_above(self._prices, self._sma) > 0:
                shares = int(self.getBroker().getCash() * 0.9 / bars[self._instrument].getPrice())
                # Enter a buy market order. The order is good till canceled.
                self._position = self.enterLong(self._instrument, shares, True)
        # Check if we have to exit the position.
        elif not self._position.exitActive() and cross.cross_below(self._prices, self._sma) > 0:
            self._position.exitMarket()

feed = GenericBarFeed(Frequency.DAY, None, None)
feed.addBarsFromCSV("Sinopec", r"c:\Users\26356\Desktop\python\BUY\600028SH.new.csv")
mySMACrossOver = SMACrossOver(feed, "Sinopec", 163)  # smaPeriod

# Attach analyzers to the strategy
returnsAnalyzer = returns.Returns()
mySMACrossOver.attachAnalyzer(returnsAnalyzer)
sharpeRatioAnalyzer = sharpe.SharpeRatio()
mySMACrossOver.attachAnalyzer(sharpeRatioAnalyzer)
drawdownAnalyzer = drawdown.DrawDown()
mySMACrossOver.attachAnalyzer(drawdownAnalyzer)
tradesAnalyzer = trades.Trades()
mySMACrossOver.attachAnalyzer(tradesAnalyzer)

# Attach the plotter to the strategy.
plt = plotter.StrategyPlotter(mySMACrossOver)
# Include the SMA in the instrument's subplot to get it displayed along with the closing prices.
plt.getInstrumentSubplot("Sinopec").addDataSeries("SMA", mySMACrossOver.getSMA())
# Plot the simple returns on each bar.
plt.getOrCreateSubplot("returns").addDataSeries("Simple returns", returnsAnalyzer.getReturns())

# Run the strategy.
mySMACrossOver.run()

print("Final portfolio value1: $%.2f" % (mySMACrossOver.getBroker().getEquity()))
print("Final portfolio value2: $%.2f" % (mySMACrossOver.getResult()))
print("Cumulative returns: %.2f%%" % (returnsAnalyzer.getCumulativeReturns()[-1] * 100))
print("Sharpe ratio: %.2f" % (sharpeRatioAnalyzer.getSharpeRatio(0.03)))
print("Max. drawdown: %.2f%%" % (drawdownAnalyzer.getMaxDrawDown() * 100))
print("Longest drawdown duration: %s" % (drawdownAnalyzer.getLongestDrawDownDuration()))

# Plot the strategy.
plt.plot()